package com.pilot.game.web.websocket;

import com.pilot.game.domain.Message;
import com.pilot.game.service.MessageService;
import com.pilot.game.service.TulinRobotService;
import com.pilot.game.web.websocket.dto.ActivityDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;

import java.io.IOException;
import java.security.Principal;
import java.time.Instant;

import static com.pilot.game.config.WebsocketConfiguration.IP_ADDRESS;

@Controller
public class ActivityService implements ApplicationListener<SessionDisconnectEvent> {

    private static final Logger log = LoggerFactory.getLogger(ActivityService.class);

    private final SimpMessageSendingOperations messagingTemplate;
    private final MessageService messageService;
    private final TulinRobotService tulinRobotService;

    public ActivityService(SimpMessageSendingOperations messagingTemplate,
                           MessageService messageService,
                           TulinRobotService tulinRobotService) {
        this.messagingTemplate = messagingTemplate;
        this.messageService = messageService;
        this.tulinRobotService = tulinRobotService;
    }

    @SubscribeMapping("/topic/activity")
    @SendTo("/topic/tracker")
    public ActivityDTO sendActivity(@Payload ActivityDTO activityDTO, StompHeaderAccessor stompHeaderAccessor, Principal principal) {
        activityDTO.setUserLogin(principal.getName());
        activityDTO.setSessionId(stompHeaderAccessor.getSessionId());
        activityDTO.setIpAddress(stompHeaderAccessor.getSessionAttributes().get(IP_ADDRESS).toString());
        activityDTO.setTime(Instant.now());
        log.debug("Sending user tracking data {}", activityDTO);
        return activityDTO;
    }

    /**
     * 广播
     *
     * @param messageDto
     * @return
     */
    @MessageMapping("/topic/chat.sendMessage")
    @SendTo("/topic/public")
    public Message sendChat(@Payload Message messageDto) {
        log.debug("sendChat messageDto data {}", messageDto);
        Integer userId = messageDto.getUserId();
        messageDto.setMessageType(1);
        messageService.save(messageDto);
        messageDto.setUserId(messageDto.getToUserId());
        messageDto.setToUserId(userId);
        try {
            messageDto.setMessage(tulinRobotService.talk(messageDto.getMessage()));
        } catch (IOException e) {
            log.error("sendChat:{},{}", e.getMessage(), e);
        }
        messageDto.setStatus("success");
        messageService.save(messageDto);
        return messageDto;
    }

    /**
     * 点对点
     *
     * @param messageDto
     * @return
     */
    @MessageMapping("/topic/chat.sendToUserMessage")
    @SendToUser("/topic/sendToUser")
    public Message sendToUserMessage(@Payload Message messageDto) {
        log.debug("sendToUserMessage  messageDto data {}", messageDto);
        Integer userId = messageDto.getUserId();
        messageDto.setMessageType(1);
        messageService.save(messageDto);
        messageDto.setUserId(messageDto.getToUserId());
        messageDto.setToUserId(userId);
        try {
            messageDto.setMessage(tulinRobotService.talk(messageDto.getMessage()));
        } catch (IOException e) {
            log.error("sendChat:{},{}", e.getMessage(), e);
        }
        messageDto.setStatus("success");
        messageService.save(messageDto);
        return messageDto;
    }


    @Override
    public void onApplicationEvent(SessionDisconnectEvent event) {
        ActivityDTO activityDTO = new ActivityDTO();
        activityDTO.setSessionId(event.getSessionId());
        activityDTO.setPage("logout");
        messagingTemplate.convertAndSend("/topic/tracker", activityDTO);
    }
}
